﻿#include "logutils.h"

#include <QTime>
#include <QDateTime>
#include <QFile>
#include <QFileInfo>
#include <QDebug>
#include <QDir>
#include <QFileInfoList>
#include <iostream>

namespace LOGUTILS
{
  static QString logFileName;
  static QString inforFileName;

  void initLogFileName()
  {
    logFileName = QString(logFolderName + "/Log_%1_%2.txt")
                  .arg(QDate::currentDate().toString("yyyy_MM_dd"))
                  .arg(QTime::currentTime().toString("hh_mm_ss_zzz"));
    inforFileName = QString(logFolderName + "/Log_%1_%2_Info.txt")
            .arg(QDate::currentDate().toString("yyyy_MM_dd"))
            .arg(QTime::currentTime().toString("hh_mm_ss_zzz"));
  }

  /**
   * @brief deletes old log files, only the last ones are kept
   */
  void deleteOldLogs()
  {
    QDir dir;
    dir.setFilter(QDir::Files | QDir::Hidden | QDir::NoSymLinks);
    dir.setSorting(QDir::Time | QDir::Reversed);
    dir.setPath(logFolderName);

    QFileInfoList list = dir.entryInfoList();
    /*//按文件数量进行rotate，超过LOGFILES个文件，删除旧文件
    if (list.size() <= LOGFILES)
    {
      return; //no files to delete
    } else
    {
      for (int i = 0; i < (list.size() - LOGFILES); i++)
      {
        QString path = list.at(i).absoluteFilePath();
        QFile file(path);
        file.remove();
      }
    }*///

    //按文件日期进行rotate，超过LOGDAYS天的文件删除
//    qint64 dateTime;
//    // 从字符串转换为毫秒（需完整的年月日时分秒）
//    datetime.fromString("2011-09-10 12:07:50:541", "yyyy-MM-dd hh:mm:ss:zzz").toMSecsSinceEpoch();
//    // 从字符串转换为秒（需完整的年月日时分秒）
//    datetime.fromString("2011-09-10 12:07:50:541", "yyyy-MM-dd hh:mm:ss:zzz").toTime_t();
    QString temp_filetime;
    QDateTime temp_time_t ;
    QString temp_filename;
    qint64 temp_time_i = 0;
    qint64 base_time_i = 0;

    for (int i = 0; i < list.size(); i++)
    {
      temp_filename = list.at(i).fileName();
      temp_filetime = temp_filename.mid(4,19);
      temp_time_t = QDateTime::fromString(temp_filetime, "yyyy_MM_dd_hh_mm_ss");
      temp_time_i = temp_time_t.toMSecsSinceEpoch();
      base_time_i = QDateTime::currentMSecsSinceEpoch();

      if((base_time_i-temp_time_i)/1000 > (86400*LOGDAYS))//超过定义的存储天数，删除文件
      {
          QString path = list.at(i).absoluteFilePath();
          QFile file(path);
          file.remove();
      }
    }
  }

  bool initLogging()
  {
      // Create folder for logfiles if not exists
      if(!QDir(logFolderName).exists())
      {
        QDir().mkdir(logFolderName);
      }

      deleteOldLogs(); //delete old log files
      initLogFileName(); //create the logfile name

      QFile outFile(logFileName);
      if(outFile.open(QIODevice::WriteOnly | QIODevice::Append))
      {
        qInstallMessageHandler(LOGUTILS::myMessageHandler);
        return true;
      }
      else
      {
        return false;
      }

      QFile outFile_infor(inforFileName);
      if(outFile_infor.open(QIODevice::WriteOnly | QIODevice::Append))
      {
        qInstallMessageHandler(LOGUTILS::myMessageHandler);
        return true;
      }
      else
      {
        return false;
      }
  }

  void myMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString& txt)
  {
    //check file size and if needed create new log!
    {
      QFile outFileCheck(logFileName);
      int size = outFileCheck.size();

      if (size > LOGSIZE) //check current log size
      {
        deleteOldLogs();
        initLogFileName();
      }
      QFile outFileCheck_info(logFileName);
      int size_info = outFileCheck_info.size();

      if (size_info > LOGSIZE) //check current log size
      {
        deleteOldLogs();
        initLogFileName();
      }
    }

    QFile outFile(logFileName);
    outFile.open(QIODevice::WriteOnly | QIODevice::Append);
    QTextStream ts(&outFile);

    QFile outFile_infor(inforFileName);
    outFile_infor.open(QIODevice::WriteOnly | QIODevice::Append);
    QTextStream ts_infor(&outFile_infor);
    //ts << txt << endl;

    QString txt_type;
    switch(type)
    {
        case QtDebugMsg:
            txt_type = QString("[Debug]");
            break;
        case QtWarningMsg:
            txt_type = QString("[Information]");
            break;
        case QtCriticalMsg:
            txt_type = QString("[Critical]");
            break;
        case QtFatalMsg:
            txt_type = QString("[Fatal]");
    }

    QString txt_info = QString("File:%1 Line:%2").arg(QString(context.file)).arg(context.line);
    QString txt_datetime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");//"yyyy-MM-dd hh:mm:ss ddd"(ddd 星期)


    QString txt_msg = QString("%1(%2):%3(%4)\r\n").arg(txt_type).arg(txt_datetime).arg(txt).arg(txt_info);

    if(txt_msg.contains("[Information]")){
        ts_infor << txt_msg << endl;
    }
    else
        ts << txt_msg << endl;
  }
}
